﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Thor.Configuration
{
    public class ConfigurationSettings
    {
        #region fields

        private IConfigurationSettingsProvider _provider;
        private string _providerAssembly = string.Empty;
        private string _providerType = string.Empty;

        #endregion

        #region constructors

        public ConfigurationSettings()
            : this(AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["ConfigurationProviderAssembly"],
                ConfigurationManager.AppSettings["ConfigurationProviderType"]) { }

        public ConfigurationSettings(string providerAssembly, string providerType)
        {
            _providerAssembly = providerAssembly;
            _providerType = providerType;
        }

        #endregion

        #region properties

        private IConfigurationSettingsProvider Provider
        {
            get
            {
                if (_provider == null)
                    _provider = GetProvider();

                return _provider;
            }
        }

        public string ProviderAssembly
        {
            get { return _providerAssembly; }
            set
            {
                if(_providerAssembly != value)
                {
                    _providerAssembly = value;
                    _provider = GetProvider();
                }
            }
        }

        public string ProviderType
        {
            get { return _providerType; }
            set
            {
                if (_providerType != value)
                {
                    _providerType = value;
                    _provider = GetProvider();
                }
            }
        }

        public string ApplicationNameKey { get { return Provider.GetConfigurationSettingValue("ApplicationNameKey"); } }
        public string ApplicationNameValue { get { return Provider.GetConfigurationSettingValue("ApplicationNameValue"); } }
        public string ConnectionStringKey { get { return Provider.GetConfigurationSettingValue("ConnectionStringKey"); } }
        public string ConnectionStringValue { get { return Provider.GetConfigurationSettingValue("ConnectionStringValue"); } }
        public string ContainerAddressKey { get { return Provider.GetConfigurationSettingValue("ContainerAddressKey"); } }
        public string ContainerAddressValue { get { return Provider.GetConfigurationSettingValue("ContainerAddressValue"); } }
        public string DataConnectionString { get { return Provider.GetConfigurationSettingValue("DataConnectionString"); } }
        public string DiagnosticsConnectionString { get { return Provider.GetConfigurationSettingValue("DiagnosticsConnectionString"); } }
        public string SettingsRepositoryAssembly { get { return Provider.GetConfigurationSettingValue("SettingsRepositoryAssembly"); } }
        public string SettingsRepositoryType { get { return Provider.GetConfigurationSettingValue("SettingsRepositoryType"); } }
        public string CalendarRepositoryAssembly { get { return Provider.GetConfigurationSettingValue("CalendarRepositoryAssembly"); } }
        public string CalendarRepositoryType { get { return Provider.GetConfigurationSettingValue("CalendarRepositoryType"); } }
        public string AdministratorAccountRepositoryAssembly { get { return Provider.GetConfigurationSettingValue("AdministratorAccountRepositoryAssembly"); } }
        public string AdministratorAccountRepositoryType { get { return Provider.GetConfigurationSettingValue("AdministratorAccountRepositoryType"); } }
        public string InvalidLogonRepositoryAssembly { get { return Provider.GetConfigurationSettingValue("InvalidLogonRepositoryAssembly"); } }
        public string InvalidLogonRepositoryType { get { return Provider.GetConfigurationSettingValue("InvalidLogonRepositoryType"); } }
        public string AssemblyRepositoryAssembly { get { return Provider.GetConfigurationSettingValue("AssemblyRepositoryAssembly"); } }
        public string AssemblyRepositoryType { get { return Provider.GetConfigurationSettingValue("AssemblyRepositoryType"); } }
        public string MessageRepositoryAssembly { get { return Provider.GetConfigurationSettingValue("MessageRepositoryAssembly"); } }
        public string MessageRepositoryType { get { return Provider.GetConfigurationSettingValue("MessageRepositoryType"); } }
        public string QueueAddressKey { get { return Provider.GetConfigurationSettingValue("QueueAddressKey"); } }
        public string QueueAddressValue { get { return Provider.GetConfigurationSettingValue("QueueAddressValue"); } }
        public string CalendarProviderInterfaceName { get { return Provider.GetConfigurationSettingValue("CalendarProviderInterfaceName"); } }
        public string CalendarMonitorInterval { get { return Provider.GetConfigurationSettingValue("CalendarMonitorInterval"); } }
        public string InvalidLogonMonitorInterval { get { return Provider.GetConfigurationSettingValue("InvalidLogonMonitorInterval"); } }

        #endregion

        #region methods

        private IConfigurationSettingsProvider GetProvider()
        {
            Assembly assembly = Assembly.LoadFile(this.ProviderAssembly);

            Type type = assembly.GetType(this.ProviderType);
            Type[] constructorTypes = new Type[0];
            ConstructorInfo constructorInfo = type.GetConstructor(constructorTypes);

            if(constructorInfo != null)
                return constructorInfo.Invoke(new object[]{}) as IConfigurationSettingsProvider;

            return null;
        }

        #endregion
    }
}
